package com.zbkj.front.service.impl;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.zbkj.common.constants.Constants;
import com.zbkj.common.enums.*;
import com.zbkj.common.exception.CommonException;
import com.zbkj.common.exception.ExceptionCodeEnum;
import com.zbkj.common.exception.ResultException;
import com.zbkj.common.invoice.PeInvoiceApply;
import com.zbkj.common.model.order.OrderDetail;
import com.zbkj.common.model.order.OrderInfo;
import com.zbkj.common.model.product.Product;
import com.zbkj.common.model.project.ProjectInfo;
import com.zbkj.common.model.system.RandomRecord;
import com.zbkj.common.model.user.User;
import com.zbkj.common.model.user.UserBill;
import com.zbkj.common.page.CommonPage;
import com.zbkj.common.request.PageParamRequest;
import com.zbkj.common.request.order.*;
import com.zbkj.common.response.UploadResponse;
import com.zbkj.common.response.order.*;
import com.zbkj.common.response.product.ClientProductResponse;
import com.zbkj.common.response.project.AdminProjectInfoResponse;
import com.zbkj.common.token.FrontTokenComponent;
import com.zbkj.common.utils.CommonUtil;
import com.zbkj.common.utils.RandomCodeUtil;
import com.zbkj.common.vo.order.OrderConditionVo;
import com.zbkj.common.vo.project.ProjectModifyConditionVo;
import com.zbkj.common.vo.user.UserDatavalVo;
import com.zbkj.front.service.OrderHandleService;
import com.zbkj.front.service.ProjectV2HandlerService;
import com.zbkj.service.service.RandomRecordService;
import com.zbkj.service.service.SystemConfigService;
import com.zbkj.service.service.UploadService;
import com.zbkj.service.service.invoice.IPeInvoiceApplyService;
import com.zbkj.service.service.order.OrderDetailService;
import com.zbkj.service.service.order.OrderInfoService;
import com.zbkj.service.service.order.ReciveAccountService;
import com.zbkj.service.service.product.ProductService;
import com.zbkj.service.service.project.ProjectInfoService;
import com.zbkj.service.service.user.UserBillService;
import com.zbkj.service.service.user.UserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Auther:
 * @Date: 2024/9/15 16:43
 * @Description:
 */
@Slf4j
@Service
public class OrderHandleServiceImpl implements OrderHandleService {
    @Autowired
    private FrontTokenComponent frontTokenComponent;
    @Autowired
    private OrderInfoService orderInfoService;
    @Autowired
    private OrderDetailService orderDetailService;
    @Autowired
    private UserService userService;
    @Autowired
    private ProductService productService;
    @Autowired
    private UploadService uploadService;
    @Autowired
    @Lazy
    private OrderHandleService orderHandleService;
    @Autowired
    private ReciveAccountService reciveAccountService;
    @Autowired
    @Lazy
    private ProjectV2HandlerService projectV2HandlerService;
    @Autowired
    private ProjectInfoService projectInfoService;
    @Autowired
    private SystemConfigService systemConfigService;
    @Autowired
    private RandomRecordService randomRecordService;
    @Autowired
    private UserBillService userBillService;
    @Autowired
    private IPeInvoiceApplyService peInvoiceApplyService;

    @Override
    public UserRechargeResponse getUserRechargeInfo() {
        Long userId = frontTokenComponent.getLoginUserId();
        User user = userService.getUserById(userId);
        UserRechargeResponse response = new UserRechargeResponse();
        BeanUtils.copyProperties(user,response);
        response.setTotalDataval(user.getCardDataval()+user.getDataval());
        if(Objects.isNull(user.getCardExpire()) || user.getCardExpire().getTime() < System.currentTimeMillis()) {
            int num = orderDetailService.getValidYearProductOrderCount(user.getId());
            response.setBuyYearCardFlag(num>0?1:0);
        } else {
            response.setBuyYearCardFlag(1);
        }
        response.setSysTime(System.currentTimeMillis());
        return response;
    }

    @Override
    public PageInfo<ClientOrderResponse> getOrderList(PageParamRequest paramRequest) {
        List<ClientOrderResponse> orderRespList = Lists.newArrayList();
        Long userId = frontTokenComponent.getLoginUserId();
        PageInfo<OrderInfo> orderPage = orderInfoService.getOrderList(userId, paramRequest);
        List<OrderInfo> orderList = orderPage.getList();
        if(CollectionUtils.isEmpty(orderList)) {
            return CommonPage.copyPageInfo(orderPage,orderRespList);
        }
        List<Long> orderIdList = orderList.stream().map(k->k.getId()).collect(Collectors.toList());
        Map<Long, List<OrderDetail>> detailGroupMap = orderDetailService.getGroupOrderIdMap(orderIdList);
        for(OrderInfo orderInfo : orderList) {
            ClientOrderResponse orderResp = new ClientOrderResponse();
            BeanUtils.copyProperties(orderInfo,orderResp);
            //凭证图片url转换为显示集合
            orderResp.setPayVouchesList(orderInfoService.payVouchesStrToShowList(orderInfo.getPayVouches()));
            //订单明细-转换为订单明细响应对象
            List<OrderDetail> tempDetaiList = detailGroupMap.getOrDefault(orderInfo.getId(), Lists.newArrayList());
            orderResp.setOrderDetailList(orderDetailService.pojoToDetailResp(tempDetaiList));
            orderRespList.add(orderResp);
        }
        return CommonPage.copyPageInfo(orderPage,orderRespList);
    }

    @Override
    public OrderSucceResponse orderSave(ClientOrderSaveRequest saveRequest) {
        OrderSucceResponse succeResponse = new OrderSucceResponse();
        saveRequest.paramCheck();
        Date currentDate = new Date();
        Long userId = frontTokenComponent.getLoginUserId();
        User user = userService.getUserById(userId);
        userService.userValidCheck(user);
        List<Long> productIdList = saveRequest.getOrderDetailList().stream().filter(v-> Objects.nonNull(v.getProductId())).map(v->v.getProductId()).collect(Collectors.toList());
        List<Product> dbProductList = productService.getByProductIds(productIdList, Lists.newArrayList(0));
        //订单明细参数检查及组装OrderDetail对象
        List<OrderDetail> orderDetailList = orderDetailService.saveOrderParamCheckAndPojoBuild(saveRequest.getOrderDetailList(), user, dbProductList, currentDate);
        OrderInfo orderInfo = orderInfoService.saveOrderPojoBuild(user,0);
        BigDecimal calcAmount = orderDetailService.calcTotalDetailFromDetail(orderDetailList);
        if(calcAmount.compareTo(saveRequest.getTotalAmount()) != 0) {
            throw new CommonException("商品购买金已变更，请刷新后重试");
        }
        orderInfo.setTotalAmount(saveRequest.getTotalAmount());
        //获取转账备注码
        orderInfo.setTfremark(this.getTransferCode());
        orderInfo.setRemark(saveRequest.getRemark());
        orderHandleService.orderSaveHandle(orderInfo,orderDetailList);
        //组装返回响应对象
        succeResponse.setOrderNo(orderInfo.getOrderNo());
        return succeResponse;
    }

    @Override
    public ReportOrderPayResonse getReportPayConf(Long projectId) {
        Long userId = frontTokenComponent.getLoginUserId();
        ProjectInfo projectDb = projectV2HandlerService.getProjectAndCheck(projectId,userId);
        ReportOrderPayResonse  response = new ReportOrderPayResonse();
        BeanUtils.copyProperties(projectDb,response);

        BigDecimal minAmount = this.getRepOrderMinAmount();
        response.setRpoMinAmount(minAmount);
        Product product = productService.getReportProduct();
        if(Objects.nonNull(product)) {
            ClientProductResponse productResponse = new ClientProductResponse();
            BeanUtils.copyProperties(product,productResponse);
            response.setProductResponse(productResponse);
            response.setProductNum(projectDb.getTotalCharum());
            BigDecimal totalAmount = product.getProductPrice().multiply(BigDecimal.valueOf(projectDb.getTotalCharum()));
            totalAmount = Objects.nonNull(minAmount) && minAmount.compareTo(totalAmount) > 0 ? minAmount : totalAmount;
            response.setTotalAmount(totalAmount);
        }

        //报表申请订单-支付最小流量值配置
        String payMinFlowValStr = systemConfigService.getValueByKey(Constants.REPORT_ORDER_MIN_FLOW_VAL);
        if(StringUtils.isNotBlank(payMinFlowValStr)) {
            response.setRpoMinFlowVal(Long.valueOf(payMinFlowValStr));
        }
        //报表申请订单-字符扣除流量系数配置
        String charToFlowValCfg = systemConfigService.getValueByKey(Constants.REPORT_ORDER_CHAR_TO_FLOW_VAL);
        if(StringUtils.isNotBlank(charToFlowValCfg)) {
            long payVal = (BigDecimal.valueOf(projectDb.getTotalCharum()).multiply(new BigDecimal(charToFlowValCfg)).setScale(0, RoundingMode.UP)).longValue();
            response.setPayFlowVal(payVal);
            if(Objects.nonNull(response.getRpoMinFlowVal())) {
                response.setPayFlowVal(Math.max(payVal,response.getRpoMinFlowVal()));
            }
        }
        return response;
    }

    /*@Override
    public ReportOrderPayResonse getReportPayFlowPacketConf(Long projectId) {
        Long userId = frontTokenComponent.getLoginUserId();
        ProjectInfo projectDb = projectV2HandlerService.getProjectAndCheck(projectId,userId);
        ReportOrderPayResonse  response = new ReportOrderPayResonse();
        BeanUtils.copyProperties(projectDb,response);
        String charToFlowValCfg = systemConfigService.getValueByKey(Constants.REPORT_ORDER_CHAR_TO_FLOW_VAL);
        if(StringUtils.isBlank(charToFlowValCfg)) {
            throw new CommonException("报告申请字符数扣除流量比例未配置，请稍后再试");
        }
        BigDecimal charToFlowVal = new BigDecimal(charToFlowValCfg);
        long payVal = (BigDecimal.valueOf(projectDb.getTotalCharum()).multiply(charToFlowVal).setScale(0, RoundingMode.UP)).longValue();
        response.setPayFlowVal(payVal);
        //报表申请订单-支付最小流量值配置
        String payMinFlowValStr = systemConfigService.getValueByKey(Constants.REPORT_ORDER_MIN_FLOW_VAL);
        if(StringUtils.isNotBlank(payMinFlowValStr)) {
            long payMinFlowVal = Long.valueOf(payMinFlowValStr);
            response.setPayFlowVal(Math.max(payVal,payMinFlowVal));
            response.setRpoMinFlowVal(payMinFlowVal);
        }
        return response;
    }*/

    /**
     * 报告申请订单-最小订单金额限制
     */
    private BigDecimal getRepOrderMinAmount() {
        String minAmount = systemConfigService.getValueByKey(Constants.REPORT_ORDER_MIN_AMOUNT);
        if(StringUtils.isNotBlank(minAmount)) {
            return new BigDecimal(minAmount);
        }
        return null;
    }

    @Override
    public OrderSucceResponse reportOrderSave(ClientReportOrderSaveRequest saveRequest) {
        OrderSucceResponse succeResponse = new OrderSucceResponse();
        saveRequest.paramCheck();
        User user = userService.getLoginUserInfo();
        userService.userValidCheck(user);
        if(Objects.isNull(user.getCardExpire()) || user.getCardExpire().getTime() < System.currentTimeMillis()) {
            throw new ResultException(ExceptionCodeEnum.NEED_RECHARGE_ERROR.getCode(),"请先充值年卡");
        }
        ProjectInfo projectDb = projectV2HandlerService.getProjectAndCheck(saveRequest.getProjectId(),user.getId());
        if(!ProjectStatusEnum.isCompletEstimate(projectDb.getStatus())) {
            throw new CommonException("项目状态已变更，请刷新后重试");
        }
        if(!ReportApplyStatusEnum.applyStatusCheck(projectDb.getReportApplyStatus())) {
            throw new CommonException("项目报告已申请正在处理中");
        }
        List<Long> productIdList = saveRequest.getOrderDetailList().stream().filter(v-> Objects.nonNull(v.getProductId())).map(v->v.getProductId()).collect(Collectors.toList());
        List<Product> dbProductList = productService.getByProductIds(productIdList, Lists.newArrayList(0));
        List<OrderDetail> orderDetailList = orderDetailService.reportOrderParamCheckAndPojoBuild(saveRequest.getOrderDetailList(),dbProductList);
        BigDecimal calcAmount = BigDecimal.ZERO;
        long totalNum = 0;
        for(OrderDetail orderDetail : orderDetailList) {
            calcAmount = calcAmount.add(orderDetail.getTotalPrice());
            totalNum += orderDetail.getTotalDataval();
        }
        //报告申请订单-最小订单金额
        BigDecimal minAmount = this.getRepOrderMinAmount();
        calcAmount = (Objects.nonNull(minAmount) && minAmount.compareTo(calcAmount) > 0 ) ? minAmount : calcAmount;
        if(calcAmount.compareTo(saveRequest.getTotalAmount()) != 0) {
            throw new CommonException("报告包商品购买金已变更，请刷新后重试");
        }
        if(totalNum != projectDb.getTotalCharum().longValue()) {
            throw new CommonException("报告包购买字符数与项目上传字符数不匹配");
        }
        OrderInfo orderInfo = orderInfoService.saveOrderPojoBuild(user,0);
        orderInfo.setOrderType(OrderTypeEnum.TYPE1.getType());
        orderInfo.setProjectId(projectDb.getId());
        orderInfo.setTotalAmount(saveRequest.getTotalAmount());
        //获取转账备注码
        orderInfo.setTfremark(this.getTransferCode());
        orderInfo.setRemark(saveRequest.getRemark());
        orderHandleService.orderSaveHandle(orderInfo,orderDetailList);
        //组装返回响应对象
        succeResponse.setOrderNo(orderInfo.getOrderNo());
        return succeResponse;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void reportPayFlowPacketSave(Long projectId) {
        Long userId = frontTokenComponent.getLoginUserId();
        User user = userService.getUserById(userId);
        userService.userValidCheck(user);
        if(Objects.isNull(user.getCardExpire()) || user.getCardExpire().getTime() < System.currentTimeMillis()) {
            throw new ResultException(ExceptionCodeEnum.NEED_RECHARGE_ERROR.getCode(),"请先充值年卡");
        }
        ProjectInfo projectDb = projectV2HandlerService.getProjectAndCheck(projectId,user.getId());
        if(!ProjectStatusEnum.isCompletEstimate(projectDb.getStatus())) {
            throw new CommonException("项目状态已变更，请刷新后重试");
        }
        if(!ReportApplyStatusEnum.applyStatusCheck(projectDb.getReportApplyStatus())) {
            throw new CommonException("项目报告已申请正在处理中");
        }

        String charToFlowValCfg = systemConfigService.getValueByKey(Constants.REPORT_ORDER_CHAR_TO_FLOW_VAL);
        if(StringUtils.isBlank(charToFlowValCfg)) {
            throw new CommonException("报告申请字符数扣除流量比例未配置，请稍后再试");
        }
        long payVal = (BigDecimal.valueOf(projectDb.getTotalCharum()).multiply(new BigDecimal(charToFlowValCfg)).setScale(0, RoundingMode.UP)).longValue();
        //报表申请订单-支付最小流量值配置
        String payMinFlowValStr = systemConfigService.getValueByKey(Constants.REPORT_ORDER_MIN_FLOW_VAL);
        if(StringUtils.isNotBlank(payMinFlowValStr)) {
            payVal = Math.max(payVal,Long.valueOf(payMinFlowValStr));
        }
        if(payVal <= 0) {
            throw new CommonException("扣除流量包字符数错误");
        }
        //报告申请-流量值扣除
        reportDeductFlowVal(user,projectDb.getId(),payVal);
        //更新项目信息 报告中、申请通过
        ProjectInfo updateProject = new ProjectInfo();
        updateProject.setId(projectId);
        updateProject.setReportApplyStatus(ReportApplyStatusEnum.PASS_APPLY.getStatus());
        updateProject.setStatus(ProjectStatusEnum.IN_REPORT.getStatus());
        updateProject.setReportStartTime(new Date());
        //项目更新检查条件
        ProjectModifyConditionVo conditionVo = new ProjectModifyConditionVo();
        conditionVo.setStatusList(Lists.newArrayList(ProjectStatusEnum.COMPLET_ESTIMATE.getStatus()));
        conditionVo.setReportApplyStatusList(ReportApplyStatusEnum.applyCheckStatusList());
        boolean updateFlag = projectInfoService.updateProject(updateProject, conditionVo);
        if(!updateFlag) {
            throw new CommonException("项目信息已变更，请稍后再试");
        }
        //申请报告计费后插入订单，类型为 申请报告订单
        OrderInfo orderInfo = new OrderInfo();
        orderInfo.setOrderNo(CommonUtil.getRandomStr(""));
        orderInfo.setOrderType(1);
        orderInfo.setSourceType(0);
        orderInfo.setUserId(userId);
        orderInfo.setUserPhone(user.getPhone());
        orderInfo.setCompanyName(user.getCompanyName());
        orderInfo.setOrderStatus(2);
        orderInfo.setProjectId(projectId);
        orderInfoService.save(orderInfo);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void orderSaveHandle(OrderInfo orderInfo, List<OrderDetail> orderDetailList) {
        if(OrderTypeEnum.isType1(orderInfo.getOrderType())) {
            //申请报告订单-更新项目报告申请状态
            projectInfoService.reportApplyStatusUpdate(orderInfo.getProjectId(), ReportApplyStatusEnum.IN_APPLY.getStatus());
        }
        boolean flag = orderInfoService.save(orderInfo);
        if(!flag) {
            throw new CommonException("订单保存失败");
        }
        try {
            //保存转账码到随机表中-防止重复
            RandomRecord randomRecord = new RandomRecord();
            randomRecord.setType(0);
            randomRecord.setSourceId(orderInfo.getId());
            randomRecord.setRcode(orderInfo.getTfremark());
            randomRecordService.saveRecord(randomRecord);
        } catch (Exception e) {
            throw new CommonException("转账备注码生成失败，请重试");
        }
        for(OrderDetail orderDetail : orderDetailList) {
            orderDetail.setOrderId(orderInfo.getId());
        }
        //保存订单明细
        orderDetailService.saveBatch(orderDetailList);
    }

    @Override
    public ClientOrderResponse getOrderPayment(String orderNo) {
        Long userId = frontTokenComponent.getLoginUserId();
        OrderInfo orderInfo = this.getOrderInfoAndCheck(orderNo,userId);
        List<OrderDetail> orderDetailList = orderDetailService.getListByOrderIds(Lists.newArrayList(orderInfo.getId()));
        ClientOrderResponse orderResponse = new ClientOrderResponse();
        BeanUtils.copyProperties(orderInfo, orderResponse);
        List<OrderDetailResponse> detailRespList = Lists.newArrayList();
        for(OrderDetail orderDetail : orderDetailList) {
            OrderDetailResponse detailResp = new OrderDetailResponse();
            BeanUtils.copyProperties(orderDetail, detailResp);
            detailRespList.add(detailResp);
        }
        orderResponse.setOrderDetailList(detailRespList);
        //获取收款账户信息
        orderResponse.setReciveAccount(reciveAccountService.getReciveAccountResponse());
        return orderResponse;
    }

    @Override
    public UploadResponse payVoucheUpload(MultipartFile multipartFile) {
        if(multipartFile == null || multipartFile.isEmpty()) {
            throw new CommonException("凭证文件不能为空");
        }
        String fileName = multipartFile.getOriginalFilename();
        String fileType = FilenameUtils.getExtension(fileName);

        UploadResponse uploadResponse = new UploadResponse();
        uploadResponse.setFileName(fileName);
        uploadResponse.setExtName(fileType);
        uploadResponse.setFileSize(multipartFile.getSize());
        try (InputStream in = multipartFile.getInputStream()){
            String fileUrl =  uploadService.inputStreamUpload(fileType, Constants.ORDER_DOC_PREFIX, in);
            uploadResponse.setUrl(fileUrl);
        } catch (CommonException ce) {
            throw ce;
        } catch (Exception ce) {
            throw new CommonException("凭证文件上传失败");
        }
        return uploadResponse;
    }

    @Override
    public void payVoucheSave(OrderPayVoucheSaveRequest saveRequest) {
        Long userId = frontTokenComponent.getLoginUserId();
        OrderInfo orderInfo = this.getOrderInfoAndCheck(saveRequest.getOrderNo(),userId);
        if(!OrderStatusEnum.voucheSaveStatusCheck(orderInfo.getOrderStatus())) {
            throw new CommonException("订单状态已变更，请刷新后重试");
        }
        //将保存的图片集合-转为","分隔字符串
        String vouches = orderInfoService.payVouchesToSaveStrList(saveRequest.getPayVouchesList());
        OrderInfo updateOrder = new OrderInfo();
        updateOrder.setId(orderInfo.getId());
        updateOrder.setPayVouches(vouches);
        if(OrderStatusEnum.isOrderStatus3(orderInfo.getOrderStatus())) {
            //拒绝订单从新上传凭证后-变更为待处理
            updateOrder.setOrderStatus(OrderStatusEnum.ORDER_STATUS1.getStatus());
            updateOrder.setRejectReason(" ");
        }
        OrderConditionVo conditionVo = new OrderConditionVo();
        conditionVo.setOrderStatusList(Lists.newArrayList(OrderStatusEnum.ORDER_STATUS1.getStatus(),OrderStatusEnum.ORDER_STATUS3.getStatus()));
        boolean falg = orderInfoService.updateOrder(updateOrder, conditionVo);
        if(!falg) {
            throw new CommonException("订单状态已变更，请刷新后重试");
        }
    }




    @Override
    public void cancel(String orderNo) {
        Long userId = frontTokenComponent.getLoginUserId();
        OrderInfo orderInfo = this.getOrderInfoAndCheck(orderNo,userId);
        if(!OrderStatusEnum.isOrderStatus1(orderInfo.getOrderStatus())){
            throw new CommonException("订单状态已变更，请刷新后重试");
        }
        boolean flag = this.orderCancelHandle(orderInfo, OrderStatusEnum.ORDER_STATUS5.getStatus());
        if(!flag) {
            throw new CommonException("订单状态已变更，请刷新后重试");
        }
    }

    @Override
    public boolean automCancel(Long orderId) {
        OrderInfo orderInfo = orderInfoService.getOrderInfo(orderId,null);
        if(Objects.isNull(orderInfo)) {
            return true;
        }
        if(!OrderStatusEnum.isOrderStatus1(orderInfo.getOrderStatus())){
            return true;
        }
        boolean flag = this.orderCancelHandle(orderInfo, OrderStatusEnum.ORDER_STATUS4.getStatus());
        return flag;
    }

    @Transactional(rollbackFor = Exception.class)
    public boolean orderCancelHandle(OrderInfo orderInfo, int cancelStatus) {
        if(OrderTypeEnum.isType1(orderInfo.getOrderType())) {
            //报告订单取消-更新对应项目申请状态
            projectInfoService.reportApplyStatusUpdate(orderInfo.getProjectId(),ReportApplyStatusEnum.UN_APPLY.getStatus());
        }
        OrderInfo updateOrder = new OrderInfo();
        updateOrder.setId(orderInfo.getId());
        updateOrder.setOrderStatus(cancelStatus);
        OrderConditionVo conditionVo = new OrderConditionVo();
        conditionVo.setOrderStatusList(Lists.newArrayList(OrderStatusEnum.ORDER_STATUS1.getStatus()));
        boolean flag = orderInfoService.updateOrder(updateOrder,conditionVo);
        if(!flag) {
            throw new CommonException("订单信息已变更，请刷新后重试");
        }
        return flag;
    }

    @Override
    public void registeGiftYearCardHandle(User user) {
        if(Objects.isNull(user) || Objects.isNull(user.getId())) {
            return;
        }
        //获取注册用户赠送年卡开关
        String switchVal = systemConfigService.getValueByKey(Constants.USER_REGISTE_GIFT_YEARCARD_SWITCH);
        if(StringUtils.isBlank(switchVal) || !"1".equals(switchVal)) { //未开启
            return;
        }
        //获取当前上架的年卡
        Product product = productService.getValidProductByType(ProductTypeEnum.PTYPE1.getType());
        if(Objects.isNull(product)) {
            return;
        }
        //组装订单明细
        OrderDetail orderDetail = orderDetailService.orderDetailBuild(product, 1L);
        //生成订单数据
        OrderInfo orderInfo = orderInfoService.saveOrderPojoBuild(user,0);
        orderInfo.setOrderStatus(OrderStatusEnum.ORDER_STATUS2.getStatus());
        orderInfo.setTotalAmount(orderDetail.getTotalPrice());
        orderInfo.setRemark("注册赠送年卡");
        //增加订单保存
        boolean flag = orderInfoService.save(orderInfo);
        if(!flag) {
            throw new CommonException("注册赠送年卡订单保存失败");
        }
        orderDetail.setOrderId(orderInfo.getId());
        //保存订单明细
        orderDetailService.save(orderDetail);
        UserDatavalVo userDatavalVo = new UserDatavalVo();
        userDatavalVo.setUserId(user.getId());
        userDatavalVo.setCardDataval(orderDetail.getTotalDataval());
        userDatavalVo.setDataval(0);
        userDatavalVo.setYearPid(orderDetail.getProductId());
        userDatavalVo.setPmtype(1);
        userDatavalVo.setCategoryEnum(UserBillCategoryEnum.BILL_CATEGORY6);
        userDatavalVo.setSourceType(1);
        userDatavalVo.setSourceId(orderInfo.getId());
        //组装用户账本
        List<UserBill> userBillList =  userBillService.userDataValVoToPojo(userDatavalVo);
        //更新用户流量包信息
        boolean updateFlag = userService.incrDataval(userDatavalVo, userBillList);
        if(!updateFlag) {
            throw new CommonException("赠送年卡更新用户记录失败");
        }
    }




    @Override
    public void registeGiftTryCardHandle(User user) {
        if(Objects.isNull(user) || Objects.isNull(user.getId())) {
            return;
        }
        //获取注册用户赠送年卡开关
        String switchVal = systemConfigService.getValueByKey(Constants.USER_REGISTE_GIFT_YEARCARD_SWITCH);
        if(StringUtils.isBlank(switchVal) || !"1".equals(switchVal)) { //未开启
            return;
        }
        //获取当前上架的年卡
        Product product = productService.getValidProductByType(ProductTypeEnum.PTYPE1.getType());
        if(Objects.isNull(product)) {
            return;
        }
        //组装订单明细
        OrderDetail orderDetail = orderDetailService.orderDetailBuild(product, 1L);
        //生成订单数据
        OrderInfo orderInfo = orderInfoService.saveOrderPojoBuild(user,0);
        orderInfo.setOrderStatus(OrderStatusEnum.ORDER_STATUS2.getStatus());
        orderInfo.setTotalAmount(orderDetail.getTotalPrice());
        orderInfo.setRemark("注册赠送试用包");
        //增加订单保存
        boolean flag = orderInfoService.save(orderInfo);
        if(!flag) {
            throw new CommonException("注册赠送试用包订单保存失败");
        }
        orderDetail.setOrderId(orderInfo.getId());
        //保存订单明细
        orderDetailService.save(orderDetail);
        UserDatavalVo userDatavalVo = new UserDatavalVo();
        userDatavalVo.setUserId(user.getId());
        userDatavalVo.setCardDataval(orderDetail.getTotalDataval());
        userDatavalVo.setDataval(0);
        userDatavalVo.setYearPid(orderDetail.getProductId());
        userDatavalVo.setPmtype(1);
        userDatavalVo.setCategoryEnum(UserBillCategoryEnum.BILL_CATEGORY6);
        userDatavalVo.setSourceType(1);
        userDatavalVo.setSourceId(orderInfo.getId());
        //组装用户账本
        List<UserBill> userBillList =  userBillService.userDataValVoToPojo(userDatavalVo);
        //更新用户流量包信息
        boolean updateFlag = userService.incrDataval(userDatavalVo, userBillList);
        if(!updateFlag) {
            throw new CommonException("赠送试用包更新用户记录失败");
        }
    }




    private OrderInfo getOrderInfoAndCheck(String orderNo, Long userId) {
        OrderInfo orderInfo = orderInfoService.getOrderInfo(null,orderNo);
        if(Objects.isNull(orderInfo)) {
            throw new CommonException("订单信息不存在");
        }
        if(orderInfo.getUserId().longValue() != userId.longValue()) {
            throw new CommonException("无权限操作该订单");
        }
        return orderInfo;
    }

    private String getTransferCode() {
        int retryNum = 5;
        String code = null;
        while (retryNum > 0) {
            code = RandomCodeUtil.getRandomCode(8);
            int existNum = randomRecordService.codeExistsCheck(0,code);
            if(existNum > 0) {
                retryNum -= 1;
            } else {
                break;
            }
        }
        if(StringUtils.isBlank(code)) {
            throw new CommonException("转账备注码生成失败，请重试");
        }
        return code;
    }

    private void reportDeductFlowVal(User user, Long sourceId, long usedCharNum) {
        if((user.getCardDataval()+user.getDataval()) < usedCharNum) {
            throw new ResultException(ExceptionCodeEnum.NEED_RECHARGE_ERROR.getCode(),"可用流量不足，请先进行充值");
        }

        long usedDataval = 0; //流量包使用数
        long useCardDataval = 0; //订阅包使用数
        if(user.getCardDataval().longValue() < usedCharNum) {
            usedDataval = usedCharNum - user.getCardDataval();
            useCardDataval = user.getCardDataval();
        } else {
            useCardDataval = usedCharNum;
        }


        UserDatavalVo userDatavalVo = new UserDatavalVo();
        userDatavalVo.setUserId(user.getId());
        userDatavalVo.setCardDataval(useCardDataval);
        userDatavalVo.setDataval(usedDataval);
        userDatavalVo.setYearPid(useCardDataval>0?user.getCardId():null);
        userDatavalVo.setPmtype(0);
        userDatavalVo.setCategoryEnum(UserBillCategoryEnum.BILL_CATEGORY4);
        userDatavalVo.setSourceType(2);
        userDatavalVo.setSourceId(sourceId);
        //组装用户账本
        List<UserBill> userBillList =  userBillService.userDataValVoToPojo(userDatavalVo);
        boolean updateFlag = userService.deductDataval(userDatavalVo,userBillList);
        if(!updateFlag) {
            throw new CommonException("用户扣除流量失败");
        }
    }




    @Transactional(rollbackFor = Exception.class)
    public void orderStatusUpdate(OrderInfo orderInfo, Integer modifyStatus, List<Integer> checkStatusList, String rejectReason) {
        if(OrderTypeEnum.isType1(orderInfo.getOrderType())) {
            //更新项目报告申请状态
            int reportStatus = OrderStatusEnum.isOrderStatus2(modifyStatus) ? ReportApplyStatusEnum.PASS_APPLY.getStatus() :ReportApplyStatusEnum.REJECT_APPLY.getStatus();
            projectInfoService.reportApplyStatusUpdate(orderInfo.getProjectId(),reportStatus);
        }
        OrderInfo updateOrder = new OrderInfo();
        updateOrder.setId(orderInfo.getId());
        updateOrder.setOrderStatus(modifyStatus);
        updateOrder.setRejectReason(rejectReason);
        OrderConditionVo conditionVo = new OrderConditionVo();
        conditionVo.setOrderStatusList(checkStatusList);
        boolean flag = orderInfoService.updateOrder(updateOrder,conditionVo);
        if(!flag) {
            throw new CommonException("订单状态已变更，请刷新后重试");
        }
    }

//    @Override
//    @Transactional(rollbackFor = Exception.class)
//    public void orderApprovalOpen(User user, OrderInfo orderInfo, List<OrderDetail> orderDetailList) {
//        Date currentDate = new Date();
//        long cardDataval = 0, dataval = 0;
//        Long yearCardId = null;
//        for(OrderDetail detail : orderDetailList) {
//            if(ProductTypeEnum.isType1(detail.getProductType())) {
//                yearCardId = detail.getProductId();
//                cardDataval += detail.getTotalDataval().longValue();
//            } else if(ProductTypeEnum.isType2(detail.getProductType())) {
//                dataval += detail.getTotalDataval().longValue();
//            }
//        }
//        if(Objects.nonNull(yearCardId)) {
//            if((Objects.nonNull(user.getCardExpire()) && user.getCardExpire().getTime()>= currentDate.getTime())) {
//                throw new CommonException("该用户已拥用年卡，无法开通购买年卡订单");
//            }
//        }
//        UserDatavalVo userDatavalVo = new UserDatavalVo();
//        userDatavalVo.setUserId(user.getId());
//        userDatavalVo.setCardDataval(cardDataval);
//        userDatavalVo.setDataval(dataval);
//        userDatavalVo.setYearPid(yearCardId);
//        userDatavalVo.setPmtype(1);
//        userDatavalVo.setCategoryEnum(UserBillCategoryEnum.BILL_CATEGORY1);
//        userDatavalVo.setSourceType(1);
//        userDatavalVo.setSourceId(orderInfo.getId());
//        //组装用户账本
//        List<UserBill> userBillList =  userBillService.userDataValVoToPojo(userDatavalVo);
//        if(cardDataval>0 && Objects.nonNull(user.getCardExpire()) && user.getCardExpire().getTime() < currentDate.getTime()) {
//            //如果当前年卡已失效，进行失效扣除处理
//            userService.userCardExpireHandle(user);
//        }
//        //更新用户流量包信息
//        boolean updateFlag = userService.incrDataval(userDatavalVo, userBillList);
//        if(!updateFlag) {
//            throw new CommonException("用户流量记录更新失败");
//        }
//        //更新订单状态处理
//        this.orderStatusUpdate(orderInfo,OrderStatusEnum.ORDER_STATUS2.getStatus(),Lists.newArrayList(OrderStatusEnum.ORDER_STATUS1.getStatus()), null);
//    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void orderApprovalOpen(User user, OrderInfo orderInfo, List<OrderDetail> orderDetailList) {
        Date currentDate = new Date();
        long cardDataval = 0, dataval = 0;
        Long yearCardId = null;
        int yearCardCount = 0; // 购买的年卡数量

        for (OrderDetail detail : orderDetailList) {
            if (ProductTypeEnum.isType1(detail.getProductType())) {
                yearCardId = detail.getProductId();
                cardDataval += detail.getTotalDataval().longValue();
                yearCardCount += detail.getProductNum(); // 假设每个年卡产品对应1年的时长
            }
        }

//        if(Objects.nonNull(yearCardId)) {
//            if((Objects.nonNull(user.getCardExpire()) && user.getCardExpire().getTime()>= currentDate.getTime())) {
//                throw new CommonException("该用户已拥用年卡，无法开通购买年卡订单");
//            }
//        }
        UserDatavalVo userDatavalVo = new UserDatavalVo();
        userDatavalVo.setUserId(user.getId());
        userDatavalVo.setCardDataval(cardDataval);
        userDatavalVo.setDataval(-1); // 将流量包设置为无限大（-1 可以表示无限大，具体根据业务逻辑而定）
        userDatavalVo.setYearPid(yearCardId);
        userDatavalVo.setPmtype(1);
        userDatavalVo.setCategoryEnum(UserBillCategoryEnum.BILL_CATEGORY1);
        userDatavalVo.setSourceType(1);
        userDatavalVo.setSourceId(orderInfo.getId());

        userDatavalVo.setYearCardCount(yearCardCount); // 设置年卡数量
        userDatavalVo.setCurrentDate(currentDate);     // 设置当前日期

        //组装用户账本
        List<UserBill> userBillList =  userBillService.userDataValVoToPojo(userDatavalVo);
        if(cardDataval>0 && Objects.nonNull(user.getCardExpire()) && user.getCardExpire().getTime() < currentDate.getTime()) {
            //如果当前年卡已失效，进行失效扣除处理
            userService.userCardExpireHandle(user);
        }

        //更新用户流量包信息
        boolean updateFlag = userService.incrDataval(userDatavalVo, userBillList);
        if(!updateFlag) {
            throw new CommonException("用户流量记录更新失败");
        }
        //更新订单状态处理
        this.orderStatusUpdate(orderInfo,OrderStatusEnum.ORDER_STATUS2.getStatus(),Lists.newArrayList(OrderStatusEnum.ORDER_STATUS1.getStatus()), null);
    }


    @Override
    public PageInfo<InvoiceListResponse> invoiceList(InvoiceListQueryRequest invoiceListQueryRequest) {
        List<InvoiceListResponse> orderRespList = Lists.newArrayList();
        Long userId = frontTokenComponent.getLoginUserId();
        PageInfo<OrderInfo> orderPage = orderInfoService.getOrderList(userId, invoiceListQueryRequest.getPage(), invoiceListQueryRequest.getLimit(), 0);
        List<OrderInfo> orderList = orderPage.getList();
        if(CollectionUtils.isEmpty(orderList)) {
            return CommonPage.copyPageInfo(orderPage,orderRespList);
        }

        List<Long> orderIdList = orderList.stream().map(k->k.getId()).collect(Collectors.toList());
        Map<Long, List<OrderDetail>> detailGroupMap = orderDetailService.getGroupOrderIdMap(orderIdList);
        for(OrderInfo orderInfo : orderPage.getList()) {
            InvoiceListResponse response = new InvoiceListResponse();
            BeanUtils.copyProperties(orderInfo, response);
            //订单明细-转换为订单明细响应对象
            List<OrderDetail> tempDetaiList = detailGroupMap.getOrDefault(orderInfo.getId(), Lists.newArrayList());
            response.setOrderDetailList(orderDetailService.pojoToDetailResp(tempDetaiList));
            orderRespList.add(response);
        }
        return CommonPage.copyPageInfo(orderPage,orderRespList);
    }

    @Transactional
    @Override
    public boolean apply(InvoiceApplySaveRequest invoiceApplySaveRequest) {
        Long userId = frontTokenComponent.getLoginUserId();
        OrderInfo orderInfo = orderInfoService.getById(invoiceApplySaveRequest.getId());
        if(ObjectUtils.isEmpty(orderInfo)){
            throw new CommonException("请确认发票ID是否正确！");
        }
        if(ObjectUtils.isNotEmpty(orderInfo.getInvoiceFlag()) && orderInfo.getInvoiceFlag() == 1){
            throw new CommonException("当前订单已开过发票！");
        }
        if(ObjectUtils.isNotEmpty(orderInfo.getInvoiceFlag()) && orderInfo.getInvoiceFlag() == 2){
            throw new CommonException("当前订单已申请过发票！");
        }
        orderInfo.setInvoiceFlag(2);
        orderInfoService.updateById(orderInfo);
        PeInvoiceApply peInvoiceApply = new PeInvoiceApply();
        BeanUtils.copyProperties(invoiceApplySaveRequest, peInvoiceApply);
        peInvoiceApply.setId(null);
        peInvoiceApply.setOrderId(invoiceApplySaveRequest.getId());
        peInvoiceApply.setInvoiceFlag(2);
        peInvoiceApply.setDeleteFlag(0);
        peInvoiceApply.setOrderNo(orderInfo.getOrderNo());
        peInvoiceApply.setTotalAmount(orderInfo.getTotalAmount());
        peInvoiceApply.setRemark(orderInfo.getRemark());
        peInvoiceApply.setUserId(userId);
        peInvoiceApplyService.save(peInvoiceApply);
        return true;
    }

    @Override
    public PageInfo<InvoiceHistoryListResponse> invoiceHistoryList(PageParamRequest pageParamRequest) {
        List<InvoiceHistoryListResponse> orderRespList = Lists.newArrayList();
        Long userId = frontTokenComponent.getLoginUserId();
        PageInfo<PeInvoiceApply> peInvoiceApplyPageInfo = peInvoiceApplyService.getUserInvoice(pageParamRequest, userId);
        List<PeInvoiceApply> peInvoiceApplyPageInfoList = peInvoiceApplyPageInfo.getList();
        if(CollectionUtils.isEmpty(peInvoiceApplyPageInfoList)) {
            return CommonPage.copyPageInfo(peInvoiceApplyPageInfo,orderRespList);
        }
        for(PeInvoiceApply peInvoiceApply : peInvoiceApplyPageInfoList) {
            InvoiceHistoryListResponse response = new InvoiceHistoryListResponse();
            BeanUtils.copyProperties(peInvoiceApply, response);
            orderRespList.add(response);
        }
        return CommonPage.copyPageInfo(peInvoiceApplyPageInfo,orderRespList);
    }
}
